package cs276.pe1.spell;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import cs276.util.Counter;
import cs276.util.StringUtils;

/**
 * Spelling corrector that uses edit distances - extends KGramSpellingCorrector.
 * @author alecmgo@gmail.com
  */
public class KGramWithEditDistancesSpellingCorrector extends KGramSpellingCorrector {
  private Logger logger = Logger.getLogger("cs276.pe1.spell.KGramWithEditDistancesSpellingCorrector");
  
  public List<String> corrections(String wordToCheck) {
    return correctionsVersion2(wordToCheck);
  }
  
  /**
   * Returns words ranked by (1 / Edit Distance)
   * @param wordToCheck
   * @return
   */
  public List<String> correctionsVersion2(String wordToCheck) {
    List<String> corrections = super.corrections(wordToCheck);
    Counter<String> rankedWords = new Counter<String>(); 
    for(String s : corrections) {
      Double rank = StringUtils.levenshtein(s, wordToCheck);
      logger.fine("rank: " + rank);
      rankedWords.setCount(s, 1 / rank);
    }
    return rankedWords.topK(TOPK_SIZE);  
  }
  
  /**
   * Returns the words sorted ascending, since a low distance is good 
   * @param wordToCheck
   * @return
   * @deprecated because slower than version 2
   */
  public List<String> correctionsVersion1(String wordToCheck) {
    List<String> corrections = super.corrections(wordToCheck);
    Counter<String> rankedWords = new Counter<String>(); 
    for(String s : corrections) {
      Double rank = StringUtils.levenshtein(s, wordToCheck);
      rankedWords.setCount(s, rank);
    }
    
    //Reverse results
    List<String> topK = rankedWords.topK(TOPK_SIZE);
    List<String> results = new ArrayList<String>();
    for(int i = topK.size() - 1; i >= 0; i--) {
      results.add(topK.get(i));
    }
    return results;     
  }
}
